<template>
    <div>
        <NuxtLayout name="default">
            <template #panel>
                <!-- <TheSession /> -->
                <ElScrollbar class="w-[240px] bg-white" ref="scrollbarRef">
                    <div class="p-[16px]">
                        <input
                            class="bg-[#f8f8f8] w-full leading-[32px] rounded-[3px] outline-none px-[10px]"
                            v-model="keyword"
                            placeholder="请输入关键词搜索"
                        />
                        <DropDown
                            v-for="(item, index) in sidebarList"
                            :title="item.name"
                            :length="item.skillList.length"
                            :key="index"
                        >
                            <template #menu>
                                <div
                                    class="bg-[#F8F8F8] flex items-center p-[10px] mt-2 cursor-pointer"
                                    :class="{
                                        actived: selectval == item1.id,
                                        unactived: selectval != item1.id
                                    }"
                                    v-for="(item1, index1) in item.skillList"
                                    :key="index1"
                                    @click="handleselected(item1)"
                                >
                                    <ElImage
                                        :src="item1.image"
                                        class="w-[34px] h-[34px] rounded-[8px]"
                                    ></ElImage>
                                    <div class="ml-2 flex-1">
                                        <div class="font-bold">
                                            {{ item1.name }}
                                        </div>
                                        <ClientOnly>
                                            <OverflowTooltip
                                                teleported
                                                class="text-tx-secondary"
                                                :content="item1.remarks"
                                                :line="2"
                                            >
                                            </OverflowTooltip>
                                        </ClientOnly>
                                    </div>
                                </div>
                            </template>
                        </DropDown>
                    </div>
                </ElScrollbar>
            </template>
            <div class="h-full">
                <Chatting
                    v-model:chat="chatParams.chatKey"
                    v-model:model="chatParams.modelKey"
                    class="h-full"
                    ref="chattingRef"
                    :title="chatTitle"
                    :selectval="selectval"
                    :avatar="currentIcon"
                    :chat-type="3"
                    :send-disabled="isReceiving"
                    :content-list="chatContentList"
                    @close="chatClose"
                    @update="getChatList"
                    @content-post="contentPost"
                    @clean-chat-log="cleanChatLog"
                ></Chatting>
            </div>
            <TheGuidedPopup ref="guidedPopupRef" />
        </NuxtLayout>
    </div>
</template>
<script setup lang="ts">
import { ElImage, ElInput, ElMessageBox, ElScrollbar } from 'element-plus'
import { getSkillList } from '@/api/skill'
import { getchatLog, getChat, cleanChat, chatSendText } from '@/api/chat'
import { useUserStore } from '~~/stores/user'
import feedback from '~~/utils/feedback'
import { useAppStore } from '~/stores/app'
import { watchDebounced } from '@vueuse/core'
const route = useRoute()
const router = useRouter()
const appStore = useAppStore()
const userStore = useUserStore()
//当前选中的侧边栏
const selectval = ref(0)
//聊天框标题
const chatTitle = ref('')
const currentIcon = ref('')
//侧边栏列表
const sidebarList = ref([])

const currentId = ref(Number(route.query.id))
const chatParams = reactive({
    chatKey: '',
    modelKey: ''
})
//滚动条ref
const scrollbarRef = ref<InstanceType<typeof ElScrollbar>>()
    
//选择侧边栏列表
const handleselected = ({ id, title, image }: any) => {
    router.push({
        path: '/skill',
        query: {
            id
        }
    })
    chatContentList.value = []
    selectval.value = Number(id)
    chatTitle.value = title
    currentIcon.value = image
    nextTick(async () => {
        await getChatList()
        chattingRef.value.scrollToBottom()
    })
}

//对话记录列表
const chatContentList: any = ref([])
//对话框ref
const chattingRef = ref(null)
const guidedPopupRef = shallowRef()
const keyword = ref()
//侧边栏列表数据
const getSidebarList = async () => {
    sidebarList.value = await getSkillList({
        keyword: keyword.value
    })
}

const actions = ref<string>('')
//获取聊天记录
const getChatList = async () => {
    let data = await getchatLog({
        type: 3,
        otherId: selectval.value,
        action: actions.value
    })
    actions.value = ''
    data = data?.map((item: any) => {
        if (item.type == 1) {
            return { ...item, fromAvatar: userStore.userInfo.avatar }
        } else {
            return { ...item, fromAvatar: currentIcon.value }
        }
    })
    chatContentList.value = data
}
//发送问题
const { pauseAll } = useAudioPlay()
const isReceiving = ref(false)
const newUserInput = ref<string>('')
const contentPost = async (userInput: any) => {
    try {
        isReceiving.value = true
        chatContentList.value.push({
            type: 1,
            content: userInput,
            fromAvatar: userStore.userInfo.avatar
        })
        chatContentList.value.push({
            type: 2,
            loading: true,
            content: [],
            fromAvatar: currentIcon.value,
            id: ''
        })
        await chatSendText(
            {
                question: userInput,
                type: 3,
                otherId: selectval.value,
                ...chatParams
            },
            {
                onstart(reader) {
                    streamReader = reader
                    pauseAll()
                },
                onmessage(value) {
                    value
                        .trim()
                        .split('data:')
                        .forEach(async (text) => {
                            if (text !== '') {
                                try {
                                    const dataJson = JSON.parse(text)
                                    const {
                                        id: chatId,
                                        event,
                                        data,
                                        index,
                                        error
                                    } = dataJson

                                    console.log(dataJson)

                                    if (error && error.errCode === 101) {
                                        guidedPopupRef.value?.open()
                                        return
                                    } else if (error) {
                                        feedback.msgError(error.errMsg)
                                        return
                                    }

                                    let chatIndex =
                                        chatContentList.value.findIndex(
                                            (item) => item.id === chatId
                                        )
                                    if (chatIndex === -1) {
                                        chatIndex =
                                            chatContentList.value.length - 1

                                        chatContentList.value[chatIndex].id =
                                            chatId
                                    }

                                    if (data) {
                                        if (
                                            !chatContentList.value[chatIndex]
                                                .content[index]
                                        ) {
                                            chatContentList.value[
                                                chatIndex
                                            ].content[index] = ''
                                        }
                                        chatContentList.value[
                                            chatIndex
                                        ].content[index] += data
                                    }

                                    if (event === 'finish') {
                                        chatContentList.value[
                                            chatIndex
                                        ].loading = false
                                        return
                                    }
                                } catch (error) {}
                            }
                        })
                },
                onclose() {
                    isReceiving.value = false
                    setTimeout(async () => {
                        await getChatList()
                        await nextTick()
                        chattingRef.value.scrollToBottom()
                    }, 400)
                    userStore.getUser()
                }
            }
        )
        chattingRef.value.cleanInput()
    } catch (error) {
        isReceiving.value = false
        chattingRef.value.setInput(newUserInput.value)
        chatContentList.value.splice(chatContentList.value.length - 2, 2)
    }
    nextTick(() => {
        chattingRef.value.scrollToBottom()
    })
}

let streamReader: ReadableStreamDefaultReader<Uint8Array> | null = null
const chatClose = (index?: number) => {
    actions.value = 'stop'
    streamReader?.cancel()
    if (index) {
        chatContentList.value[index].loading = false
    }
    isReceiving.value = false
}

//清空会话
const cleanChatLog = async () => {
    await feedback.confirm('确定清空对话？')
    await cleanChat({ type: 3, otherId: selectval.value })
    chatContentList.value = []
}

//选择侧边栏列表第一个选项
const selectFirst = () => {
    if (!currentId.value && sidebarList.value[0]?.skillList.length) {
        handleselected(sidebarList.value[0]?.skillList[0])
    } else {
        sidebarList.value.forEach((item, index) => {
            item.skillList.forEach((item1, index1) => {
                if (item1.id == currentId.value) {
                    handleselected(sidebarList.value[index].skillList[index1])
                }
            })
        })
    }
}

const scrollCategory = () => {
    const [activeCategory] = document.getElementsByClassName('actived')
    if (!activeCategory) return
    const activeCategoryRect = activeCategory.getBoundingClientRect()
    const categoryScrollbarRect =
        scrollbarRef.value?.wrapRef.getBoundingClientRect()
    const scrollTop =
        activeCategoryRect.top -
        (categoryScrollbarRect.height / 2 + categoryScrollbarRect.top)
    scrollbarRef.value.setScrollTop(scrollTop)
}


onMounted(async () => {
    await getSidebarList()
    await selectFirst()
    scrollCategory()
})

watchDebounced(
    keyword,
    (value) => {
        getSidebarList()
    },
    {
        debounce: 500
    }
)

definePageMeta({
    layout: false
})
</script>
<style lang="scss" scoped>
.actived {
    border-left: 3px solid var(--el-color-primary);
}
.unactived {
    border-left: 3px solid #f8f8f8;
}
</style>
